package com.plata.base.aclr.utils;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;

public class StringUtils {
    private static final String TAG = "StringUtils";

    private static final String[] SIZE_UNITS = {"B", "KB", "MB", "GB", "TB", "EB", "ZB", "YB"};
    private static final String[] TIME_UNITS = {"ps", "ns", "μs", "ms", "s"};
    private static final String[] TIME2_UNITS = {"ms", "s", "m", "h"};
    private static final String FORMAT_NUMBER_UNIT = "%s %s";

    /**
     * Get the keys from a set of string parameter
     *
     * @param params
     * @return
     */
    public static HashMap<String, String> parseParams(String params) {
        if (isEmpty(params)) {
            return null;
        }
        HashMap<String, String> hashMap = new HashMap<String, String>();
        String[] paramArray = params.split("&");
        String[] array = null;
        for (String param : paramArray) {
            array = param.split("=");
            if (null != array && array.length == 2) {
                hashMap.put(array[0].trim(), array[1].trim());
            }
        }
        return hashMap;
    }

    public static String formatTime2(long time) {
        int level = 0;
        if (time < 1000) {
            return String.format(FORMAT_NUMBER_UNIT, time, TIME2_UNITS[level]);
        }

        time /= 1000;
        level++;

        while (time > 60) {
            time /= 60;
            if (++level >= (TIME2_UNITS.length - 1)) {
                break;
            }
        }

        return String.format(FORMAT_NUMBER_UNIT, time, TIME2_UNITS[level]);
    }

    public static String formatTime(double time) {
        int level = 1;
        while (time > 1000) {
            time /= 1000;
            if (++level >= (TIME_UNITS.length - 1)) {
                break;
            }
        }

        if (((int) (time * 10)) % 10 == 0) {
            return String.format(FORMAT_NUMBER_UNIT, ((int) (time * 10)) / 10, TIME_UNITS[level]);
        }
        return String.format(FORMAT_NUMBER_UNIT, ((int) (time * 10)) / 10D, TIME_UNITS[level]);
    }

    public static String formatSpeed(DecimalFormat decimalFormater, double speed) {
        return formatSize(decimalFormater, speed) + "/s";
    }

    public static String formatSize(DecimalFormat decimalFormater, double size) {
        int level = 0;
        while (size > 1024) {
            size /= 1024;
            level++;
        }
        return String.format(FORMAT_NUMBER_UNIT, decimalFormater.format(size), SIZE_UNITS[level]);
    }

    /**
     * Check a string is empty or not.
     *
     * @param str
     * @return
     */
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0 || str.trim().length() == 0 || "null".equalsIgnoreCase(str);
    }

    public static String getRandomNumber() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("0.");

        Random random = new Random();
        int count = random.nextInt(11) + 10;
        for (int i = 0; i <= count; i++) {
            if (i == count) {
                stringBuilder.append(random.nextInt(9) + 1);
                break;
            }
            stringBuilder.append(random.nextInt(10));
        }

        return stringBuilder.toString();
    }

    /**
     * Gets the integer type of the string version number
     *
     * @param versionString
     * @return
     */
    public static long getVersionNum(String versionString) {
        if (isEmpty(versionString)) {
            return 0;
        }

        long versionNum = 0;

        try {
            String[] versionArray = versionString.split("\\.");
            for (int i = 0; i < versionArray.length; i++) {
                if (i == (versionArray.length - 1)) {
                    versionNum += Long.valueOf(versionArray[i]);
                } else {
                    versionNum += Long.valueOf(versionArray[i]) * Math.pow(10, versionArray.length - i);
                }
            }
        } catch (Exception e) {
            LogTool.e(TAG, "", e);
        }

        return versionNum;
    }

    /**
     * Check whether a string is numeric.
     *
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }

        int length = str.length();
        for (int i = 0; i < length; i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public static String join(Object[] elements, CharSequence separator) {
        return join(Arrays.asList(elements), separator);
    }

    public static String join(Iterable<? extends Object> elements, CharSequence separator) {
        StringBuilder builder = new StringBuilder();

        if (elements != null) {
            Iterator<? extends Object> iter = elements.iterator();
            if (iter.hasNext()) {
                builder.append(String.valueOf(iter.next()));
                while (iter.hasNext()) {
                    builder.append(separator).append(String.valueOf(iter.next()));
                }
            }
        }

        return builder.toString();
    }

    public static String fixLastSlash(String str) {
        String res = str == null ? "/" : str.trim() + "/";
        if (res.length() > 2 && res.charAt(res.length() - 2) == '/') {
            res = res.substring(0, res.length() - 1);
        }
        return res;
    }

    public static int convertToInt(String str) throws NumberFormatException {
        int s, e;
        for (s = 0; s < str.length(); s++) {
            if (Character.isDigit(str.charAt(s))) {
                break;
            }
        }
        for (e = str.length(); e > 0; e--) {
            if (Character.isDigit(str.charAt(e - 1))) {
                break;
            }
        }
        if (e > s) {
            try {
                return Integer.parseInt(str.substring(s, e));
            } catch (NumberFormatException ex) {
                LogTool.e(TAG, "convertToInt failed. " + ex.toString());
                throw new NumberFormatException();
            }
        } else {
            throw new NumberFormatException();
        }
    }

    public static String generateTime(long time) {
        int totalSeconds = (int) (time / 1000);
        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours = totalSeconds / 3600;

        return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
    }

    private StringUtils() {
    }
}
